package com.xncoding.wechat.utils;

import com.xncoding.wechat.dto.BankCardElement;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

@Component
public class CryptoUtil {

    /**
     * Base64编码
     */
    public String base64Encode(String data) {
        return Base64.encodeBase64String(data.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * Base64解码
     */
    public String base64Decode(String data) {
        byte[] decoded = Base64.decodeBase64(data);
        return new String(decoded, StandardCharsets.UTF_8);
    }

    /**
     * AES加密（需要与财付通协商密钥）
     */
    public String aesEncrypt(String data, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.encodeBase64String(encrypted);
    }

    /**
     * AES解密（需要与财付通协商密钥）
     */
    public String aesDecrypt(String encryptedData, String key) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decoded = Base64.decodeBase64(encryptedData);
        byte[] decrypted = cipher.doFinal(decoded);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    /**
     * 加密银行要素块
     */
    public String encryptBankElement(BankCardElement element, String key) throws Exception {
        String plainText = String.format("cre_type=%d&cre_id=%s&true_name=%s",
                element.getCreType(), element.getCreId(), element.getTrueName());
        return aesEncrypt(plainText, key);
    }

    /**
     * 解密银行要素块
     */
    public BankCardElement decryptBankElement(String encryptedData, String key) throws Exception {
        String decrypted = aesDecrypt(encryptedData, key);
        String[] parts = decrypted.split("&");

        BankCardElement element = new BankCardElement();
        for (String part : parts) {
            String[] keyValue = part.split("=", 2);
            if (keyValue.length == 2) {
                switch (keyValue[0]) {
                    case "cre_type":
                        element.setCreType(Integer.parseInt(keyValue[1]));
                        break;
                    case "cre_id":
                        element.setCreId(keyValue[1]);
                        break;
                    case "true_name":
                        element.setTrueName(keyValue[1]);
                        break;
                }
            }
        }
        return element;
    }
}